package com.qingzhuge.manager.security.service;

import com.qingzhuge.common.enums.ERoleType;
import com.qingzhuge.manager.entity.SysRole;
import com.qingzhuge.manager.service.ISysRoleService;
import com.qingzhuge.resource.entity.SysResource;
import com.qingzhuge.resource.service.ISysResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author zeroxiao
 * @date 2019/9/12 10:05
 * 权限验证数据源
 * <p>
 * 此处实现
 * 从数据库中获取URL对应的role信息
 */
public class DefinedFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Autowired
    private ISysResourceService resourceService;

    @Autowired
    private ISysRoleService roleService;

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        String requestUrl = ((FilterInvocation) o).getRequestUrl();
        String method = ((FilterInvocation) o).getRequest().getMethod();
        SysResource resource = resourceService.findByUrlAndRequestMethod(requestUrl, method);
        List<String> roleIds = new ArrayList<>();
        if (resource != null) {
            SysRole role = new SysRole();
            role.setResources(Collections.singletonList(resource));
            List<SysRole> all = roleService.findAll(role);
            all.forEach(sysRole -> {
                ERoleType type = sysRole.getType();
                if (type != null) {
                    roleIds.add(type.name());
                }
            });
        }
        return SecurityConfig.createList(roleIds.toArray(new String[0]));
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }
}